home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 6 / MacAddict_006_1997_02.iso / Software Updates / MacsBug 6.5.3 / Building dcmds / C Samples / File.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-22  |  10.5 KB  |  415 lines  |  [TEXT/MPS ]

  1. /*
  2.  
  3.     File:        File.c
  4.  
  5.     Contains:    This is the FCB dcmd.
  6.  
  7.     Written by:    JM3 = Jim Murphy
  8.                 DAL = Dave Lyons
  9.                 sad = Scott Douglas
  10.  
  11.     Copyright:    © 1988,1993-1996 by Apple Computer, Inc., all rights reserved.
  12.  
  13.     Change History (most recent first):
  14.  
  15.         <11>   27-Jan-96    JM3        And the project lead declared, “alpha! beta! final! GM!”
  16.         <10>   25-Jan-96    JM3        Added sample build commands.
  17.          <9>     10/5/95    DAL        Made source legible. Options still don't combine, though. Could
  18.                                     use more work, but it's mo-better than before.
  19.          <8>     10/4/95    DAL        Added -t type option. Version 3.0.2d1. Ya know, this command is
  20.                                     *really* unreadable, thanks in large part to me. It is begging
  21.                                     to be whaled upon mightily...de-elsed and disentangled. There
  22.                                     are now enough options that the combinations should work, like
  23.                                     'file "Sys" -t MACS', but they don't combine.
  24.          <7>     4/18/95    DAL        Omit some boring fields from the "file 0" display (for logs).
  25.          <6>     2/21/95    DAL        Made "file 0" show all open files except for fonts (to help
  26.                                     shrink Standard Logs). Bumped version to 3.0.1.
  27.          <5>   10-Dec-94    JM3        Updated for new format 3 dcmd requirements.
  28.          <4>     5/13/94    DAL        Deal with carriage returns inside filenames (changed put.c).
  29.          <3>   24-Jan-94    JM3        With the Universal Interfaces, EqualString is now in
  30.                                     TextUtils.h. Blah.
  31.          <2>     9/13/93    DAL        made some columns wider and fixed the filename-prefix feature to
  32.                                     work again
  33.  
  34.     Old history:
  35.  
  36.         29Nov88 sad        revised for new dcmd names.
  37.          5Oct88    sad        broke out formatting routines to put.c
  38.         30Sep88 sad        written
  39.  
  40.     The following MPW commands will build the dcmd and copy it to the "Debugger Prefs" file
  41.     in the System folder. The dcmd's name in MacsBug will be the name of the file built by
  42.     the Linker.
  43.  
  44.     C File.c
  45.     Link -o File -sg Main=STDCLIB,STDIO,SANELIB dcmdGlue.a.o File.c.o Put.c.o ∂
  46.         "{Libraries}Runtime.o" "{Libraries}Interface.o"
  47.     BuildDcmd File 194 -format3
  48.     Echo 'include "File";'    |    Rez -a -o "{SystemFolder}Debugger Prefs"
  49.  
  50. */
  51.  
  52. #include <Types.h>
  53. #include <Memory.h>
  54. #include <Files.h>
  55. #include <OSUtils.h>
  56. #include <TextUtils.h>
  57.  
  58. #include "dcmd.h"
  59. #include "put.h"
  60.  
  61.  
  62. //----------------------------------------------------------------------------------------
  63. // ••• Lomem stuff •••
  64. //----------------------------------------------------------------------------------------
  65.  
  66. #define FSFCBLen 0x3f6
  67. #define FCBsPtr  0x34e
  68.  
  69.  
  70. typedef struct FCB
  71. {
  72.     unsigned long fcbFlNum;
  73.     unsigned char fcbMdRByt;
  74.     unsigned char fcbTypByt;
  75.     unsigned short fcbSBlk;
  76.     unsigned long fcbEOF;
  77.     unsigned long fcbPLen;
  78.     unsigned long fcbCrPs;
  79.     VCB* fcbVPtr;
  80.     void* fcbBfAdr;
  81.     unsigned short fcbFlPos;
  82.     unsigned long fcbClmpSize;
  83.     void* fcbBTCBPtr;
  84.     unsigned long fcbExtRec[3];
  85.     OSType fcbFType;
  86.     unsigned long fcbCatPos;
  87.     unsigned long fcbDirID;
  88.     char fcbCName[32];
  89. }
  90.     FCB;
  91.  
  92.  
  93. //----------------------------------------------------------------------------------------
  94. // DrawHeader:
  95. //----------------------------------------------------------------------------------------
  96. static void DrawHeader(Boolean shortForm)
  97. {
  98. //                                 1         2         3         4         5         6         7
  99. //                        1234567890123456789012345678901234567890123456789012345678901234567890
  100.  
  101.     if (shortForm)
  102.         dcmdDrawLine("\pfRef File                   Vol         Type Fl Fork     LEof");
  103.     else
  104.         dcmdDrawLine("\pfRef File                   Vol         Type Fl Fork     LEof     Mark  FlNum Parent FCB at");
  105. }
  106.  
  107.  
  108. //----------------------------------------------------------------------------------------
  109. // IsFontFile:
  110. //----------------------------------------------------------------------------------------
  111. static Boolean IsFontFile(FCB *fcbp)
  112. {
  113.     OSType filetype = fcbp->fcbFType;
  114.  
  115.     if (filetype == 'FFIL' || filetype == 'ffil' || filetype == 'tfil')
  116.         return true;
  117.  
  118.     return false;
  119. }
  120.  
  121.  
  122. //----------------------------------------------------------------------------------------
  123. // DrawFCB:
  124. //----------------------------------------------------------------------------------------
  125. static void DrawFCB(int fref, FCB* fcbp, Boolean shortForm)
  126. {
  127.     PutUHexWord(fref);
  128.     PutSpace();
  129.     PutPStrTruncTo(fcbp->fcbCName, 17+10);
  130.     PutSpace();
  131.     PutPStrTruncTo(fcbp->fcbVPtr->vcbVN, 26+10+3);
  132.     PutSpace();
  133.     PutOSType(fcbp->fcbFType);
  134.     PutSpace();
  135.     PutChar((fcbp->fcbMdRByt & 0x80) ? 'D' : 'd');
  136.     PutChar((fcbp->fcbMdRByt & 0x01) ? 'W' : 'w');
  137.     PutSpace();
  138.     if (fcbp->fcbMdRByt & 0x02)
  139.         PutPStr("\prsrc ");
  140.     else
  141.         PutPStr("\pdata ");
  142.     PutUDecTo(fcbp->fcbEOF,47+11+3);
  143.  
  144.     if (!shortForm)
  145.     {
  146.         PutSpace();
  147.         PutUDecTo(fcbp->fcbCrPs,55+12+3);
  148.         PutSpace();
  149.         PutUHexZTo(fcbp->fcbFlNum,6,62+12+3);
  150.         PutSpace();
  151.         PutUHexZTo(fcbp->fcbDirID,6,69+12+3);
  152.         PutSpace();
  153.         PutUHexZTo((unsigned long)fcbp,6,76+12+3);
  154.     }
  155.  
  156.     PutLine();
  157. }
  158.  
  159.  
  160. //----------------------------------------------------------------------------------------
  161. // PrefixPStr
  162. //         returns true if astr is equal to a prefix of bstr.
  163. //        (astr must not be longer than 31 characters)
  164. //----------------------------------------------------------------------------------------
  165. static Boolean PrefixPStr(const Str255 astr, const Str255 bstr)
  166. {
  167.     char newstr[31];
  168.     int alen = *astr;
  169.     int blen = *bstr;
  170.  
  171.     if (alen <= blen)
  172.     {
  173.         BlockMoveData(bstr+1, newstr+1, alen);
  174.         newstr[0] = alen;
  175.         return EqualString(astr, newstr, false, true);
  176.     }
  177.  
  178.     return false;    
  179. }
  180.  
  181.  
  182. //----------------------------------------------------------------------------------------
  183. // DoHelp:
  184. //----------------------------------------------------------------------------------------
  185. static void DoHelp(void)
  186. {
  187.     dcmdDrawLine("\pDisplays file information on all open files, or for the given fRefNum,");
  188.     dcmdDrawLine("\pfilename, or for all files of the given filetype. Flags are D/d=Dirty,");
  189.     dcmdDrawLine("\pW/w=writeable.  \"file 0\" shows all open files except for fonts.");
  190. }
  191.  
  192.  
  193.  
  194. //----------------------------------------------------------------------------------------
  195. // ••• parsed options •••
  196. //----------------------------------------------------------------------------------------
  197.  
  198. Boolean gDoOneFCB, gHaveFileName;
  199. OSType gFiletype;
  200. long gRefnum;
  201.  
  202.  
  203. //----------------------------------------------------------------------------------------
  204. // DoFileCommand:
  205. //----------------------------------------------------------------------------------------
  206. void DoFileCommand(dcmdBlock *paramPtr)
  207. {
  208.     short    c;
  209.     int        fcbLen;                // the length of one fcb
  210.     char*    fcbsbase;
  211.     int        fcbslen;            // the length of the fcbs block
  212.     Str255    filename;
  213.  
  214.     gDoOneFCB = false;
  215.     gHaveFileName = false;
  216.     gFiletype = 0;
  217.  
  218.     dcmdDrawLine("\pDisplaying File Control Blocks");
  219.  
  220.     fcbLen   = * (unsigned short *) FSFCBLen;
  221.     fcbsbase = * (char **) FCBsPtr;
  222.     fcbslen  = * (unsigned short *) fcbsbase;
  223.  
  224.     if (fcbLen != sizeof(FCB))
  225.     {
  226.         PutPStr("\FSFCBLen = ");
  227.         PutUDec(fcbLen);
  228.         PutPStr("\p expected ");
  229.         PutUDec(fcbLen);
  230.         PutLine(sizeof(FCB));
  231.         return;
  232.     }
  233.  
  234.     if ((fcbslen - 2) % fcbLen != 0)
  235.     {
  236.         PutPStr("\pBad fcbslen ");
  237.         PutUHexWord(fcbslen);
  238.         PutLine();
  239.         return;
  240.     }
  241.  
  242.     c = dcmdPeekAtNextChar();
  243.     if (c == '"' || c == '\'')
  244.     {
  245.         gHaveFileName = true;
  246.         (void) dcmdGetNextParameter(filename);    // get the filename ('file "name"')
  247.     }
  248.     else if (c == '-')        // look for "-t type"
  249.     {
  250.         dcmdGetNextParameter(filename);
  251.         if (filename[0] != 2 || filename[1] != '-' || filename[2] != 't')    // not "-t" ?
  252.         {
  253.             PutPStr("\pBad option");
  254.             PutLine();
  255.             return;
  256.         }
  257.  
  258.         dcmdGetNextParameter(filename);        // get the filetype ('file -t type')
  259.         gFiletype = '    ';
  260.         if (filename[0] == 0 || filename[0] > 4)
  261.         {
  262.             PutPStr("\pBad filetype");
  263.             PutLine();
  264.             return;
  265.         }
  266.  
  267.         BlockMoveData(&filename[1], &gFiletype, filename[0]);
  268.     }
  269.     else
  270.     {
  271.         (void) dcmdGetNextExpression(&gRefnum, &gDoOneFCB);        // get single file refnum
  272.     }
  273.  
  274.  
  275.     // ••• handle 'file <refnum>' (display info on a single file)
  276.  
  277.     if (gDoOneFCB && gRefnum)
  278.     {
  279.         FCB *fcbp;
  280.  
  281.         gRefnum = (unsigned short) gRefnum;
  282.         if ((gRefnum > fcbslen) || ((gRefnum - 2) % fcbLen != 0))
  283.         {
  284.             PutPStr("\pBad file refnum ");
  285.             PutUHexWord(gRefnum);
  286.             PutLine();
  287.             return;
  288.         }
  289.  
  290.         fcbp = (FCB *) (gRefnum + fcbsbase);
  291.  
  292.         if (fcbp->fcbFlNum)
  293.         {
  294.             DrawHeader(false /* long form */);
  295.             DrawFCB(gRefnum, fcbp, false /* long form */);
  296.             return;
  297.         }
  298.  
  299.         PutPStr("\pFCB ");
  300.         PutUHexWord(gRefnum);
  301.         PutPStr("\p is not in use");
  302.         PutLine();
  303.         return;
  304.     }
  305.  
  306.  
  307.     // ••• handle 'file' and 'file 0' (show all open files, or abbreviated form of all files)
  308.  
  309.     {
  310.         int numFCBs = (fcbslen - 2) / fcbLen;
  311.         int fcbsUsed = 0;
  312.         int numFontsSkipped = 0;
  313.         Boolean foundOne = false;
  314.     
  315.         for (gRefnum = 2; gRefnum < fcbslen; gRefnum += fcbLen)
  316.         {
  317.             FCB* fcbp = (FCB *) (fcbsbase + gRefnum);
  318.  
  319.             if (paramPtr->aborted)
  320.                 return;
  321.  
  322.             if (!fcbp->fcbFlNum)    // if ______, skip this one
  323.                 continue;
  324.  
  325.             if (gHaveFileName && !PrefixPStr(filename, fcbp->fcbCName))
  326.                 continue;            // skip if it doesn't begin with specified name
  327.     
  328.             if (gFiletype && (gFiletype != fcbp->fcbFType))
  329.                 continue;
  330.     
  331.             fcbsUsed++;
  332.  
  333.             if (!foundOne++)                // draw header the first time
  334.                 DrawHeader(gDoOneFCB);        // true = short form ("file 0")
  335.  
  336.             if (gDoOneFCB && IsFontFile(fcbp))        // gDoOneFCB here means there was a refnum (0) on the command line
  337.                 numFontsSkipped++;
  338.             else
  339.                 DrawFCB(gRefnum, fcbp, gDoOneFCB /* true for short form (for 'file 0') */);
  340.         }
  341.  
  342.  
  343.         // summarize the results
  344.     
  345.         if (gHaveFileName)
  346.         {
  347.             if (!foundOne)
  348.             {
  349.                 PutPStr("\pNo open files match \"");
  350.                 PutPStr(filename);
  351.                 PutChar('"');
  352.                 PutLine();
  353.             }
  354.             return;
  355.         }
  356.  
  357.         if (gFiletype != 0)        // for now, don't summarize if we filtered by filetype
  358.             return;
  359.  
  360.         PutUDec(numFCBs);
  361.         PutPStr("\p FCBs, ");
  362.         PutUDec(fcbsUsed);
  363.         PutPStr("\p in use");
  364.  
  365.         if (numFontsSkipped)
  366.         {
  367.             PutPStr("\p (including ");
  368.             PutUDec(numFontsSkipped);
  369.             PutPStr("\p fonts not listed)");
  370.         }
  371.         PutPStr("\p, ");
  372.  
  373.         PutUDec(numFCBs - fcbsUsed);
  374.         PutPStr("\p free");
  375.         PutLine();
  376.     }
  377. }
  378.  
  379.  
  380. //----------------------------------------------------------------------------------------
  381. // CommandEntry:
  382. //----------------------------------------------------------------------------------------
  383. pascal void CommandEntry(dcmdBlock* paramPtr)
  384. {
  385.     switch (paramPtr->request)
  386.     {
  387.         case dcmdInit:
  388.             break;
  389.  
  390.         case dcmdHelp:
  391.             DoHelp();
  392.             break;
  393.  
  394.         case dcmdGetInfo:
  395.         {
  396.             static const char usageStr[] = "\p[fRefNum | \"file name\" | -t \"type\"]";
  397.  
  398.             * (long *) &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->dcmdVersion = 0x03028000; // version 3.0.2
  399.             BlockMoveData(&usageStr, &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->usageStr, usageStr[0]+1);
  400.             break;
  401.         }
  402.  
  403.         case dcmdDoIt:
  404.             dcmdSwapWorlds();
  405.             DoFileCommand(paramPtr);
  406.             dcmdSwapWorlds();
  407.             break;
  408.  
  409.         // Format 3 and newer dcmds must quietly ignore requests we don't recognize.
  410.  
  411.         default:
  412.             break;
  413.     }
  414. }
  415.